<template>
  <div class="map-view">
    <div class="map-box">
      <div id="map"></div>
    </div>

    <div class="poi-list">
      <el-tabs v-model="poiKey" @tab-click="handleTabClick">
        <el-tab-pane v-for="tab in tabs" :label="tab.name" :key="tab.value" :name="tab.value" :lazy="true">
          <div class="poi-list-ov" v-if="list[tab.value]">
            <ol>
              <li class="poi-list-item" v-for="poi in list[tab.value].pois" :key="poi" @mouseover="_ => showPoi(poi)">
                <span class="name">{{ poi.name }}</span>
                <span class="distance">{{ getDistance(poi.location) }}公里</span>
              </li>
            </ol>
          </div>
          <div class="extra-info" v-if="tab.value === 'scenic' || tab.value === 'traffic'">
            <h3 v-if="tab.value === 'scenic'">风景优美</h3>
            <h3 v-if="tab.value === 'traffic'">交通便利</h3>
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>
  </div>
</template>

<script>
const poiTypeNameMap = {
  scenic: '风景名胜',
  traffic: '交通设施服务'
}
const url = '//webapi.amap.com/maps?v=1.4.14&key=37bf7f90d1c870a433d2c426467bc5fe&callback=onAMapLoad';

export default {
  props: ['dataSource'],
  data() {
    return {
      tabs: [{ value: 'scenic', name: '风景' }, { value: 'traffic', name: '交通' }],
      poiKey: '',
      activePointer: null,
      list: {
        scenic: {},
        traffic: {},
      }
    }
  },

  mounted() {
    this.poiKey = 'scenic'

    const jsapi = document.createElement('script');
    jsapi.charset = 'utf-8';
    jsapi.src = url;

    document.head.appendChild(jsapi);
    window.onAMapLoad = () => {
      const map = new AMap.Map('map')
      this.map = map

      this.addMarks()
      this.addPoiList()
    }
  },

  computed: {
    position() {
      const { location: { latitude, longitude } } = this.dataSource
      return new AMap.LngLat(longitude, latitude)
    },

    poiType() {
      return poiTypeNameMap[this.poiKey]
    },

    locationList() {
      const { name, address, location: { latitude, longitude } } = this.dataSource
      const hotelData = { name, address, location: `${longitude},${latitude}` }
      const { pois: poiList = [] } = this.list[this.poiKey]

      return [hotelData, ...poiList]
    },
  },

  methods: {
    renderMark(item, i) {
      const { name, address, location } = item
      const position = new AMap.LngLat(...location.split(','))
      const content = item.id ?
        `<span class="marker" data-id=${item.id}>${i}</span>`
        : '<span class="marker hotel-marker" />'
      const marker = new AMap.Marker({
        position,
        title: name,
        content,
        text: address,
        extData: item.id,
        // animation: 'AMAP_ANIMATION_DROP',
        topWhenClick: true,
      })
      if (!item.id) {
        marker.setzIndex(9999)
      }
      marker.on('mouseover', _ => this.showPoi(item))
      return marker
    },

    addMarks() {
      if (typeof AMap !== 'object') {
        return
      }
      const map = this.map
      const markers = this.locationList.map(this.renderMark)
      map.clearMap()
      map.add(markers);//添加到地图
      map.setFitView();
    },

    addPoiList() {
      const types = this.poiType
      const { real_city } = this.dataSource
      const { lng, lat } = this.position
      if (this.list[this.poiKey].pois) {
        return
      }
      this.$axios({
        url: 'https://restapi.amap.com/v3/place/text', params: {
          keywords: '',
          city: real_city,
          location: `${lng},${lat}`,
          types,
          output: 'json',
          page: 1,
          offset: 10,
          key: '37bf7f90d1c870a433d2c426467bc5fe'
        }
      }).then(r => {
        this.list[this.poiKey] = r.data
        this.addMarks()
      })
    },

    getDistance(p) {
      const distance = AMap.GeometryUtil.distance(this.position, p.split(','))
      return (distance / 1000).toFixed(2)
    },

    handleTabClick(v) {
      this.poiKey = v.name
      this.addPoiList()
      this.addMarks()
    },

    showPoi(poi) {
      this.map.getAllOverlays('marker').forEach(m => {
        if (m.getExtData() === poi.id) {
          // m.setAnimation('AMAP_ANIMATION_DROP')
          m.setTop(true)
          const infoWindow = new AMap.InfoWindow({
            content: `<span style="font-size: 12px;color: #333">${m.getTitle()}</span>`,
            offset: new AMap.Pixel(0, -32),
          })
          infoWindow.open(this.map, m.getPosition())
          this.map.setCenter(m.getPosition())
        }
      })
    }
  }
}
</script>

<style scoped lang="less">
.extra-info {
    position: relative;
    top: -10px;
  }
.map-view {
  display: flex;
  flex: 1;
  height: 360px;
}

.map-box {
  width: 65%;
  height: 100%;
}

#map {
  width: 100%;
  height: 100%;
}

.poi-list {
  flex: 1;
  background-color: #fff;
  padding-left: 20px;

  .poi-list-ov {
    height: 300px;
    overflow: auto;
    font-size: 14px;
    color: #666;
  }

  .poi-list-item {
    display: flex;
    margin: 0 20px 20px 10px;
    cursor: pointer;

    .name {
      flex: 1;
    }
  }
}

@keyframes jump {
  0% {
    transform: translateY(0);
  }

  50% {
    transform: translateY(-20px);
  }

  100% {
    transform: translateY(0);
  }
}

/deep/ .marker {
  display: inline-block;
  width: 22px;
  height: 36px;
  background-image: url(https://webapi.amap.com/theme/v1.3/markers/b/mark_b.png);
  background-size: 22px 36px;
  text-align: center;
  line-height: 24px;
  color: #fff;

  &.hotel-marker {
    background-image: url(/images/mark_b.png);
    background-size: 22px 36px;
  }

  &.active {
    animation: jump 0.25s ease-in 3;
  }
}</style>
